/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "zlang_in.h"

int InterpretExpression_MemberOf( struct ZlangRuntime *rt , struct ZlangObject *master_obj , struct ZlangObject **result_obj )
{
	struct ZlangTokenDataUnitHeader	*token_info1 = NULL ;
	char				*token1 = NULL ;
	struct ZlangTokenDataUnitHeader	*token_info2 = NULL ;
	char				*token2 = NULL ;
	struct ZlangObject		*prop_obj = NULL ;
	
	int				nret = 0 ;
	
	TEST_RUNTIME_DEBUG_THEN_PRINT_ENTER_FUNCTION(rt)
	
	TRAVELTOKEN_AND_SAVEINFO( rt , token_info1 , token1 )
	if( token_info1->token_type == TOKEN_TYPE_IDENTIFICATION ) /* func_name or prop_name in object */
	{
		QueryCharsetAliasAndChangeTokenInfo( rt , token_info1 , & token1 );
		
		PEEKTOKEN( rt , token_info2 , token2 )
		if( token_info2->token_type == TOKEN_TYPE_BEGIN_OF_SUB_EXPRESSION ) /* ( */
		{
			NEXTTOKEN( rt )
			
			nret = InterpretExpression_InvokeFunction( rt , master_obj , token1 , result_obj ) ;
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "GetExpression_InvokeFunction return[%d]" , nret )
			if( nret )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT_INTERRUPT_FUNCTION(rt)
				return nret;
			}
		}
		else
		{
			prop_obj = QueryPropertyInObjectByPropertyName( rt , master_obj , token1 ) ;
			TEST_RUNTIME_DEBUG( rt ) { PRINT_TABS_AND_FORMAT( rt , "QueryPropertyInObjectByPropertyName prop_name[%s] return prop[%p]" , token1 , prop_obj ); }
			if( prop_obj == NULL )
			{
				SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_PROP_NOT_FOUND_IN_OBJECT , "property '%s' not found in object '%s'" , token1 , GetObjectName(master_obj) )
				TEST_RUNTIME_DEBUG_THEN_PRINT_INTERRUPT_FUNCTION(rt)
				return ZLANG_ERROR_PROP_NOT_FOUND_IN_OBJECT;
			}
			
			(*result_obj) = prop_obj ;
		}
	}
	else
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_SYNTAX , "unexpect method or property" )
		TEST_RUNTIME_DEBUG_THEN_PRINT_INTERRUPT_FUNCTION(rt)
		return ZLANG_ERROR_SYNTAX;
	}
	
	TEST_RUNTIME_DEBUG_THEN_PRINT_LEAVE_FUNCTION(rt)
	
	return 0;
}

